package com.kloyf.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

import java.util.ArrayList;
import java.util.List;

/**
 * Redis配置
 *
 * @author chencq
 * @email chenchaoqun@incar100.com
 */
@Configuration
public class RedisConfig {

    private static final Logger LOG = LoggerFactory.getLogger(RedisConfig.class);

    @Autowired
    private RedisPoolProperties redisPoolProperties;


    @Bean
    public JedisPoolConfig getJedisPoolConfig() {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxIdle(redisPoolProperties.getMaxIdle());
        config.setMaxWaitMillis(redisPoolProperties.getMaxWaitMillis());
        config.setMaxTotal(redisPoolProperties.getMaxTotal());
        config.setMinIdle(redisPoolProperties.getMinIdle());
        config.setTestOnBorrow(redisPoolProperties.getTestOnBorrow());
        config.setTestOnReturn(redisPoolProperties.getTestOnReturn());
        config.setJmxEnabled(redisPoolProperties.getJmxEnabled());
        config.setBlockWhenExhausted(redisPoolProperties.getBlockWhenExhausted());
        return config;
    }

    @Bean
    public RedisClusterConfiguration getRedisClusterConfiguration() {
        RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
        String node = redisPoolProperties.getNodes();
        String[] serverArray = node.split(";");
        List<RedisNode> nodes = new ArrayList<>();
        for (String ipPort : serverArray) {
            String[] ipPortPair = ipPort.split(":");
            RedisNode redisNode = new RedisNode(ipPortPair[0].trim(), Integer.valueOf(ipPortPair[1].trim()));
            nodes.add(redisNode);
        }
        redisClusterConfiguration.setClusterNodes(nodes);
        //RedisPassword redisPassword = RedisPassword.of(redisPoolProperties.getPassword());
        //redisClusterConfiguration.set(redisPassword);
        return redisClusterConfiguration;
    }


    @Bean
    public RedisConnectionFactory getRedisConnectionFactory() {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(getRedisClusterConfiguration());
        jedisConnectionFactory.setPoolConfig(getJedisPoolConfig());
        jedisConnectionFactory.setDatabase(redisPoolProperties.getDatabase());
        jedisConnectionFactory.setPassword(redisPoolProperties.getPassword());
        return jedisConnectionFactory;
    }


    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        redisTemplate.setConnectionFactory(getRedisConnectionFactory());
        return redisTemplate;
    }

    @Bean
    public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForHash();
    }

    @Bean
    public ValueOperations<String, String> valueOperations(RedisTemplate<String, String> redisTemplate) {
        return redisTemplate.opsForValue();
    }

    @Bean
    public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForList();
    }

    @Bean
    public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForSet();
    }

    @Bean
    public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForZSet();
    }

    ///**
    // * 创建连接工厂
    // *
    // * @param connectionFactory
    // * @return
    // */
    //@Bean
    //public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
    //    RedisMessageListenerContainer container = new RedisMessageListenerContainer();
    //    container.setConnectionFactory(connectionFactory);
    //    return container;
    //}

}
